package com.heima.user.service.impl;

import com.alibaba.nacos.api.utils.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.user.dtos.RegisterDto;
import com.heima.model.user.dtos.UserDto;
import com.heima.model.user.pojos.ApUser;
import com.heima.model.user.dtos.LoginDto;
import com.heima.user.mapper.ApUserMapper;
import com.heima.user.service.ApUserService;
import com.heima.utils.common.AppJwtUtil;
import com.heima.utils.common.SendSms;
import com.heima.utils.common.ValidateCodeUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;

import javax.servlet.http.HttpSession;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
@Slf4j
@Service
@Transactional
public class ApUserServiceImpl extends ServiceImpl<ApUserMapper, ApUser> implements ApUserService {

    /**
     * 登录
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult login(LoginDto dto) {
        //判断手机号和密码是否有值
        if (!StringUtils.isBlank(dto.getPhone()) && !StringUtils.isBlank(dto.getPassword())) {
            //走到这里说明有值,创建Lqw对象
            LambdaQueryWrapper<ApUser> lqw = new LambdaQueryWrapper<>();
            //设置条件,根据手机号查询
            lqw.eq(ApUser::getPhone, dto.getPhone());
            //调用service查询
            ApUser user = getOne(lqw);
            //非空判断
            if (user == null) {
                //响应错误信息
                return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "用户不存在");
            }
            //获取盐
            String salt = user.getSalt();
            //获取用户录入的密码
            String password = dto.getPassword();
            //加盐
            password = DigestUtils.md5DigestAsHex((password + salt).getBytes());
            //比对
            if (!password.equals(user.getPassword())) {
                //响应错误信息
                return ResponseResult.errorResult(AppHttpCodeEnum.LOGIN_PASSWORD_ERROR);
            }
            //创建集合
            Map<String, Object> map = new HashMap<>();
            //存入信息
            map.put("token", AppJwtUtil.getToken(user.getId().longValue()));
            //设置盐
            user.setSalt("");
            //设置密码
            user.setPassword("");
            //把用户存入集合
            map.put("user",user);
            //响应
            return ResponseResult.okResult(map);
        }else {
            //走到这里说明是游客登录,创建集合
            Map<String, Object> map = new HashMap<>();
            //存入信息
            map.put("token",AppJwtUtil.getToken(0L));
            //响应
            return ResponseResult.okResult(map);
        }
    }

    /**
     * 发送短信
     * @param registerDto
     * @return
     */
    @Override
    public ResponseResult sendMsg(RegisterDto registerDto, HttpSession session) {
        //获取手机号
        String phone = registerDto.getPhone();
        //判断长度
        if (phone.length() != 11){
            //响应失败,手机号位数有问题
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID,"手机号验证失败,请重新输入");
        }
        //创建Lqw对象
        LambdaQueryWrapper<ApUser> lqw = new LambdaQueryWrapper<>();
        //设置条件,根据手机号查询
        lqw.eq(ApUser::getPhone,phone);
        //查询
        ApUser user = getOne(lqw);
        //判断
        if (user != null){
            //响应失败,该手机号已被注册
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_EXIST,"手机号已被注册");
        }
        //获取验证码
        String code = ValidateCodeUtils.generateValidateCode4String(4);
        //输出密码
        log.warn("验证码:" + code);
        //调用工具类发送短信
        //SendSms.sendMsg(phone,code);
        //存入session
        session.setAttribute("code",code);
        //把手机号进行返回
        return ResponseResult.okResult(phone);
    }

    /**
     * 注册
     * @param registerDto
     * @param session
     * @return
     */
    @Override
    public ResponseResult register(RegisterDto registerDto, HttpSession session) {
        //从session中获取验证码
        String code = null;
        try {
            code = session.getAttribute("code").toString();
        } catch (Exception e) {
            e.printStackTrace();
            //说明验证码过期了
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID,"验证码过期");
        }
        //删除session
        session.removeAttribute("code");
        //判断
        if (!code.equals(registerDto.getCode())){
            //响应失败,验证码错误
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID,"验证码错误");
        }
        //把手机号存入session中
        session.setAttribute("phone",registerDto.getPhone());
        //响应成功
        return ResponseResult.okResult(200,"注册成功");
    }

    /**
     * 保存用户信息
     * @param userDto
     * @param session
     * @return
     */
    @Override
    public ResponseResult saveUser(UserDto userDto, HttpSession session) {
        //创建User对象
        ApUser apUser = new ApUser();
        //获取手机号
        String phone = session.getAttribute("phone").toString();
        //删除session
        session.removeAttribute("phone");
        //判断两次密码是否一致
        if (!userDto.getPassword().equals(userDto.getAgainPassword())){
            //响应失败,密码不一致
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID,"密码不一致");
        }
        //使用UUID生成随机盐
        String salt = UUID.randomUUID().toString().replace("-", "").substring(0, 16);
        //跟密码进行加密
        String password = DigestUtils.md5DigestAsHex((salt + userDto.getPassword()).getBytes());
        //封装数据
        apUser.setPassword(password);
        apUser.setSalt(salt);
        apUser.setCreatedTime(new Date());
        apUser.setName(userDto.getUsername());
        apUser.setPhone(phone);
        //保存到数据库
        save(apUser);
        //响应成功
        return ResponseResult.okResult(200,"保存成功");
    }


}
